package cn.com.surker.sale.service.impl;

import cn.com.surker.common.Code;
import cn.com.surker.database.JDBCTemplateCache;
import cn.com.surker.enums.system.DataBaseEnum;
import cn.com.surker.sale.dao.SaleContractAddStereDao;
import cn.com.surker.sale.dao.SaleContractDao;
import cn.com.surker.sale.entity.SaleContract;
import cn.com.surker.sale.entity.SaleContractAddStere;
import cn.com.surker.sale.service.SaleContractAddStereBaseService;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.dao.DataSourceInfoDao;
import cn.com.surker.system.dao.SysMessageRecordDao;
import cn.com.surker.system.dao.SysUserDao;
import cn.com.surker.system.dao.SysUserPositionDao;
import cn.com.surker.system.entity.DataSourceInfo;
import cn.com.surker.system.entity.SysMessageRecord;
import cn.com.surker.system.entity.SysUser;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.StringUtils;
import cn.com.surker.vo.sale.SaleContractVo;
import cn.com.surker.wechat.WechatOaGroupApi;
import cn.com.surker.wechat.WechatSurkerGroupApi;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author lucky
 * @create 2024年07月21 16:54
 * @desc
 */
@Slf4j
public abstract class SaleContractAddStereBaseServiceImpl extends ServiceImpl<SaleContractAddStereDao, SaleContractAddStere> implements SaleContractAddStereBaseService {

    @Resource
    protected SaleContractAddStereDao saleContractAddStereDao;
    @Resource
    protected SaleContractDao saleContractDao;
    @Resource
    private DataSourceInfoDao dsDao;
    @Resource
    private SysUserPositionDao userPositionDao;
    @Resource
    private SysMessageRecordDao sysMessageRecordDao;
    @Resource
    private SysUserDao userDao;


    /**
     * 转量操作
     * @param masterConId 操作主合同
     * @param slaverConId 操作从合同
     * @param stere
     * @param remark
     * @param creator
     * @return
     */
    public RestResultDto tranStere(Long masterConId, Long slaverConId, Double stere, String remark, String creator) {
        if (StringUtils.isAllParamNull(masterConId, slaverConId, stere))
            return RestResultDto.fail("参数错误");
        Integer type = 0;//0 转入 1 转出
        if (stere < 0)
            type = 1;
        if (masterConId.intValue() == slaverConId.intValue())
            return RestResultDto.fail("转入与转出合同不能是同一个合同");

        SaleContractVo masterContract = saleContractDao.selectById(masterConId);//主合同
        if (masterContract == null || masterContract.getStatus().intValue() == 1)
            return RestResultDto.fail("操作主合同不存在或已被删除");
        SaleContractVo slaverContract = saleContractDao.selectById(slaverConId);//子合同
        if (slaverContract == null || slaverContract.getStatus().intValue() == 1)
            return RestResultDto.fail("操作子合同不存在或已被删除");
        Double masterSumStere = masterContract.getSumStere();
        Double slaverSumStere = slaverContract.getSumStere();
        SaleContractAddStere masterAdd = new SaleContractAddStere();
        SaleContractAddStere slaverAdd = new SaleContractAddStere();
        Date nowDate = new Date();
        String masterRemark = "";
        String slaverRemark = "";
        if (type == 0) {
            masterRemark = "转出" + (-stere) + "m³至合同[" + slaverContract.getName() + "]";
            slaverRemark = "合同[" + masterContract.getName() + "]转入" + (-stere) + "m³";
        } else {
            slaverRemark = "转出" + (-stere) + "m³至合同[" + slaverContract.getName() + "]";
            masterRemark = "合同[" + masterContract.getName() + "]转入" + (-stere) + "m³";
        }
        masterAdd = new SaleContractAddStere(masterContract.getOrgId(), masterConId, -stere,
                masterRemark, creator, nowDate);
        masterContract.setAddStere(StringUtils.addDouble(masterContract.getAddStere(), -stere));
        masterContract.setSumStere(StringUtils.addDouble(masterContract.getSumStere(), -stere));
        masterContract.setUpdateTime(nowDate);
        slaverAdd = new SaleContractAddStere(slaverContract.getOrgId(), slaverConId, stere,
                slaverRemark, creator, nowDate);
        slaverContract.setAddStere(StringUtils.addDouble(slaverContract.getAddStere(), stere));
        slaverContract.setSumStere(StringUtils.addDouble(slaverContract.getSumStere(), stere));
        slaverContract.setUpdateTime(nowDate);

        Double masterSendStere = 0.0;//主合同发货量
        Double slaverSendStere = 0.0;//子合同发货量
        if (!StringUtils.isNull(masterContract.getErpid()) && masterContract.getErpid().intValue() > 0
                && !StringUtils.isNull(slaverContract.getErpid()) && slaverContract.getErpid().intValue() > 0) {
            if (masterContract.getOrgId().intValue() == slaverContract.getOrgId().intValue()) {
                DataSourceInfo ds = dsDao.queryDSByOriginId(masterContract.getOrgId());
                if (ds == null)
                    return RestResultDto.fail("合同数据源不存在");
                JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
                Object[] obj1 = {masterContract.getErpid()};
                /**合同总方量**/
                String sendSql = "select ISNULL(SUM(a3.VerifyStere),0) sendStere from Market_Contract_T a1 left join Market_Indent_T a2 " +
                        " on a1.ID = a2.Market_Contract_ID left join Production_Invoice_T a3 on a2.ID = a3.Market_Indent_ID " +
                        " where a1.IsValid = 1 and a1.id = ?  and a2.IsValid = 1 and a3.IsValid = 1 \n" +
                        "and a3.status = 2 and a3.InvoiceType = 1";
                /**发货方量**/
                masterSendStere = StringUtils.convertDouble(jdbcTemplate.queryForList(sendSql, obj1).get(0).get("sendStere"));
                obj1 = new Object[]{slaverContract.getErpid()};
                slaverSendStere = StringUtils.convertDouble(jdbcTemplate.queryForList(sendSql, obj1).get(0).get("sendStere"));
                if (type == 0) {
                    if (masterSumStere - masterSendStere < stere)
                        return RestResultDto.fail("转出合同余量小于转出方量" + stere + "m³");
                } else {
                    if (slaverSumStere - slaverSendStere < stere)
                        return RestResultDto.fail("转出合同余量小于转出方量" + stere + "m³");
                }

                StringBuffer sql = new StringBuffer();
                sql.append("insert into Market_Contract_AddStere_T (Market_Contract_ID,AddStere,Review,CreatorID,CreationTime,IsValid,remarks) values(?,?,1,?,?,1,?)");
                String nowTime = DateUtil.convertString(new Date(), "yyyy-MM-dd HH:mm:ss");
                Object[] obj = {masterContract.getErpid(), masterAdd.getAddStere(), "1", nowTime, masterAdd.getRemark()};

                log.info("addVolume:追加方量SQL:{},参数:{}", sql.toString(), obj);
                Integer code = jdbcTemplate.update(sql.toString(), obj);
                if (code > 0) {
                    obj = new Object[]{slaverContract.getErpid(), slaverAdd.getAddStere(), "1", nowTime, slaverAdd.getRemark()};
                    code = jdbcTemplate.update(sql.toString(), obj);
                }
            } else {
                DataSourceInfo masterDs = dsDao.queryDSByOriginId(masterContract.getOrgId());
                if (masterDs == null)
                    return RestResultDto.fail("合同数据源不存在");
                DataSourceInfo slaverDs = dsDao.queryDSByOriginId(slaverContract.getOrgId());
                if (slaverDs == null)
                    return RestResultDto.fail("合同数据源不存在");
                JdbcTemplate masterJdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(masterDs);
                JdbcTemplate slaverJdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(slaverDs);
                Object[] obj1 = {masterContract.getErpid()};
                /**合同总方量**/
                String sendSql = "select ISNULL(SUM(a3.VerifyStere),0) sendStere from Market_Contract_T a1 left join Market_Indent_T a2 " +
                        " on a1.ID = a2.Market_Contract_ID left join Production_Invoice_T a3 on a2.ID = a3.Market_Indent_ID " +
                        " where a1.IsValid = 1 and a1.id = ?  and a2.IsValid = 1 and a3.IsValid = 1 \n" +
                        "and a3.status = 2 and a3.InvoiceType = 1";
                /**发货方量**/
                masterSendStere = StringUtils.convertDouble(masterJdbcTemplate.queryForList(sendSql, obj1).get(0).get("sendStere"));
                obj1 = new Object[]{slaverContract.getErpid()};
                slaverSendStere = StringUtils.convertDouble(slaverJdbcTemplate.queryForList(sendSql, obj1).get(0).get("sendStere"));
                if (type == 0) {
                    if (masterSumStere - masterSendStere < Math.abs(stere))
                        return RestResultDto.fail("转出合同余量小于转出方量" + Math.abs(stere) + "m³");
                } else {
                    if (slaverSumStere - slaverSendStere < Math.abs(stere))
                        return RestResultDto.fail("转出合同余量小于转出方量" + Math.abs(stere) + "m³");
                }

                StringBuffer sql = new StringBuffer();
                sql.append("insert into Market_Contract_AddStere_T (Market_Contract_ID,AddStere,Review,CreatorID,CreationTime,IsValid,remarks) values(?,?,1,?,?,1,?)");
                String nowTime = DateUtil.convertString(new Date(), "yyyy-MM-dd HH:mm:ss");
                Object[] obj = {masterContract.getErpid(), masterAdd.getAddStere(), "1", nowTime, masterAdd.getRemark()};

                log.info("addVolume:追加方量SQL:{},参数:{}", sql.toString(), obj);
                Integer code = masterJdbcTemplate.update(sql.toString(), obj);
                if (code > 0) {
                    obj = new Object[]{slaverContract.getErpid(), slaverAdd.getAddStere(), "1", nowTime, slaverAdd.getRemark()};
                    code = slaverJdbcTemplate.update(sql.toString(), obj);
                }
            }
        } else {
            return RestResultDto.fail("合同ERPID参数错误");
        }
        Integer code = saleContractAddStereDao.insert(masterAdd);
        if (code > 0) {
            code = saleContractAddStereDao.insert(slaverAdd);
            if (code > 0) {
                code = saleContractDao.updateById(masterContract);
                if (code > 0) {
                    code = saleContractDao.updateById(slaverContract);
                    if (code > 0) {
                        try {
                            sendMessage(masterContract, masterAdd);
                        } catch (Exception e) {
                            log.error("发送消息失败~！");
                        }
                        try {
                            sendMessage(slaverContract, slaverAdd);
                        } catch (Exception e) {
                            log.error("发送消息失败~！");
                        }
                        return RestResultDto.success("操作成功");
                    }
                }
            }
        }

        return RestResultDto.fail("操作失败");
    }

    /**
     * 添加追加方量
     * @param contractAddStere
     * @return
     */
    public Integer saveAddStere(SaleContractAddStere contractAddStere) {
        if (contractAddStere == null)
            return Code.PARAM_EMPTY.getCode();
        if (StringUtils.isNull(contractAddStere.getContractId()))
            return Code.CONTRACT_EMPTY.getCode();
        if (StringUtils.isNull(contractAddStere.getAddStere()))
            return Code.CONTRACT_STERE_EMPTY.getCode();
        SaleContractVo saleContract = saleContractDao.selectById(contractAddStere.getContractId());
        if (saleContract == null || saleContract.getStatus().intValue() == 1)
            return Code.CONTRACT_EMPTY.getCode();
        Date nowDate = new Date();
        contractAddStere.setOrgId(saleContract.getOrgId());
        contractAddStere.setCreateTime(nowDate);
        contractAddStere.setStatus(0);
        Integer code = saleContractAddStereDao.insert(contractAddStere);
        if (code > 0) {
            saleContract.setAddStere(StringUtils.addDouble(saleContract.getAddStere(), contractAddStere.getAddStere()));
            saleContract.setSumStere(StringUtils.addDouble(saleContract.getSumStere(), contractAddStere.getAddStere()));
            saleContract.setUpdateTime(nowDate);
            code = saleContractDao.updateById(saleContract);
            if (code > 0) {
                try {
                    sendMessage(saleContract, contractAddStere);
                } catch (Exception e) {
                    log.error("发送消息失败~！");
                }
                if (!StringUtils.isNull(saleContract.getErpid()) && saleContract.getErpid().intValue() > 0) {
                    StringBuffer sql = new StringBuffer();
                    sql.append("insert into Market_Contract_AddStere_T (Market_Contract_ID,AddStere,Review,CreatorID,CreationTime,IsValid,remarks) values(?,?,1,?,?,1,?)");
                    String nowTime = DateUtil.convertString(new Date(), "yyyy-MM-dd HH:mm:ss");
                    Object[] obj = {saleContract.getErpid(), contractAddStere.getAddStere(), "1", nowTime, contractAddStere.getRemark()};
                    DataSourceInfo ds = dsDao.queryDSByOriginId(saleContract.getOrgId());
                    if (ds == null) {
                        ds = dsDao.queryDSByOriginIdV1(saleContract.getOrgId(), DataBaseEnum.MYSQL.getCode());
                        if (ds == null)
                        return -1;
                    }
                    if (ds.getType() == 0)
                        return 0;
                    log.info("addVolume:追加方量SQL:{},参数:{}", sql.toString(), obj);
                    JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
                    code = jdbcTemplate.update(sql.toString(), obj);
                    if (code > 0)
                        return 0;
                }
                if (code > 0) {
//                    String sql_ = "update Market_Contract_T set SumStere = SumStere + " + contractAddStere.getAddStere()
//                            + " where id = " + saleContract.getErpid();
//                    code = jdbcTemplate.update(sql_);
//                    if (code > 0)
                    return 0;
                }
            }
        }
        return -1;
    }

    /**
     * 分页查询追加方量信息
     * @param searchVal
     * @param startTime
     * @param endTime
     * @param status
     * @param offset
     * @param limit
     * @return
     */
    public IPage findPage(String searchVal, Long contractId, String startTime, String endTime, Integer status, Integer offset, Integer limit) {
        if (StringUtils.isNull(contractId))
            return null;
        PageHelper.offsetPage(offset, limit);
        QueryWrapper<SaleContractAddStere> query = new QueryWrapper<>();
        query.eq("contract_id", contractId);
        if (!StringUtils.isNull(status))
            query.eq("status", status);
        if (!StringUtils.isNull(startTime))
            query.ge("create_time", startTime);
        if (!StringUtils.isNull(endTime))
            query.lt("create_time", endTime);
        if (!StringUtils.isNull(searchVal))
            query.and(orderWrapper -> orderWrapper.like("remark", searchVal));
        query.orderByDesc("create_time");

        IPage<SaleContractAddStere> iPage = saleContractAddStereDao.selectPage(new Page<>((offset + limit) /limit, limit), query);
        /**分页插件**/
        if (!StringUtils.isNull(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal()))
                iPage.setTotal(pageInfo.getTotal());
        }
        return iPage;
    }

    /**
     * 追加方量消息推送
     * @param contract
     * @param contractAddStere
     */
    private void sendMessage(SaleContractVo contract, SaleContractAddStere contractAddStere) {
        if (contractAddStere.getCreator().equals("万强") || contractAddStere.getCreator().equals("罗涛")
                || contractAddStere.getCreator().equals("马杰") || contractAddStere.getCreator().equals("谭世杰"))
            return;
        Date nowDate = new Date();
        String message = "【合同方量追加】 编号:" + contract.getCode();
        message += "\n工程名称:" + contract.getClientName() + "[" + contract.getName() + "]";
        message += "\n追加方量:" + contractAddStere.getAddStere() + "m³";
        message += "\n总方量:" + contract.getSumStere() + "m³";
        message += "\n操作人:" + contractAddStere.getCreator();
        if (!StringUtils.isNull(contractAddStere.getRemark()))
            message += "\n备注:" + contractAddStere.getRemark();
        message += "\n操作时间:" + DateUtil.convertString(nowDate);

        String touser = "lucky|1lt1556|";
        String toname = "万强|罗涛|";
        List<Map<String, Object>> list = userPositionDao.hasGeneralManager(contractAddStere.getOrgId(), "销售内业", "信控专员");
        if (!StringUtils.isNull(contract.getSales())) {
            SysUser user = userDao.queryByName(contract.getSales());
            if (user != null && toname.indexOf(user.getName()) == -1) {
                toname += user.getName() + "|";
                touser += user.getUsername() + "|";
            }
        }
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Map<String, Object> temp = list.get(i);
                String name = StringUtils.convertString(temp.get("name"));
                if (!StringUtils.isNull(name) && toname.indexOf(name) == -1) {
                    toname += temp.get("name") + "|";
                    touser += temp.get("username") + "|";
                }
            }
        }

        toname = toname.substring(0, toname.length() - 1);
        touser = touser.substring(0, touser.length() - 1);
        SysMessageRecord record = new SysMessageRecord(touser, toname, "", WechatOaGroupApi.corpID, "", contractAddStere.getOrgId(),
                "", 1, 1, "合同变更推送", "",
                message, "", 1, 0, "", "", nowDate);
        sysMessageRecordDao.insert(record);
        WechatOaGroupApi.sendTextMessage(WechatOaGroupApi.corpID, WechatOaGroupApi.corpSecret,
                WechatOaGroupApi.agentId, touser, message);
    }

}
